package com.objectproject.main.dao;

import java.util.ArrayList;
import java.util.HashSet;

import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.objectproject.main.dao.iface.hierarchy.MyGroupHierarchyDAO;
import com.objectproject.main.dao.mybatis.mapper.hierarchy.MyGroupHierarchyMapper;
import com.objectproject.main.model.MyGroup;

@Repository
public class MyGroupHierarchyDAOImpl implements MyGroupHierarchyDAO {

	@Autowired
	SqlSession sqlSession;
	
	@Autowired
	MyGroupDAOImpl myGroupDAOImpl;
	
	@Override
	public ArrayList<Long> selectSuperGroupIds(long groupId) {
		return sqlSession.getMapper(MyGroupHierarchyMapper.class).selectSuperGroupIds(groupId);
	}

	@Override
	public ArrayList<Long> selectSubGroupIds(long groupId) {
		return sqlSession.getMapper(MyGroupHierarchyMapper.class).selectSubGroupIds(groupId);
	}

	@Override
	public ArrayList<MyGroup> selectSuperGroups(long groupId) {
		return sqlSession.getMapper(MyGroupHierarchyMapper.class).selectSuperGroups(groupId);
	}

	@Override
	public ArrayList<MyGroup> selectSubGroups(long groupId) {
		return sqlSession.getMapper(MyGroupHierarchyMapper.class).selectSubGroups(groupId);
	}

	@Override
	public void insertHierarchy(long groupId, long superGroupId) {
		sqlSession.getMapper(MyGroupHierarchyMapper.class).insertHierarchy(groupId, superGroupId);
	}

	@Override
	public void deleteHierarchy(long groupId, long superGroupId) {
		sqlSession.getMapper(MyGroupHierarchyMapper.class).deleteHierarchy(groupId, superGroupId);
	}

	@Override
	public ArrayList<Long> selectAncestorGroupIds(long groupId) {
		// sql 문장으로 해결하던가 그게 아니라면 여기에 로직을 구현하지 말 것
		// 일단 여기서 해결 나중에 맵퍼(mysql 내에서 이 문제가 해결된)를 사용하자.

		HashSet<Long> sumAncestorGroupIds = new HashSet<Long>();
		ArrayList<Long> readyQueue = new ArrayList<Long>();
		ArrayList<Long> tempGroupIds = new ArrayList<Long>();

		readyQueue.add(groupId);

		while (readyQueue.size() != 0) {

			tempGroupIds = sqlSession.getMapper(MyGroupHierarchyMapper.class)
					.selectSuperGroupIds(readyQueue.get(0));

			readyQueue.addAll(tempGroupIds);
			sumAncestorGroupIds.addAll(tempGroupIds);

			readyQueue.remove(0);

		}

		return new ArrayList<Long>(sumAncestorGroupIds);
	}

	@Override
	public ArrayList<Long> selectDescendantGroupIds(long groupId) {
		// sql 문장으로 해결하던가 그게 아니라면 여기에 로직을 구현하지 말 것
		// 일단 여기서 해결 나중에 맵퍼(mysql 내에서 이 문제가 해결된)를 사용하자.

		HashSet<Long> sumDescendantGroupIds = new HashSet<Long>();
		ArrayList<Long> readyQueue = new ArrayList<Long>();
		ArrayList<Long> tempGroupIds = new ArrayList<Long>();

		readyQueue.add(groupId);

		while (readyQueue.size() != 0) {

			tempGroupIds = sqlSession.getMapper(MyGroupHierarchyMapper.class)
					.selectSubGroupIds(readyQueue.get(0));

			readyQueue.addAll(tempGroupIds);
			sumDescendantGroupIds.addAll(tempGroupIds);

			readyQueue.remove(0);

		}

		return new ArrayList<Long>(sumDescendantGroupIds);
	}

	@Override
	public ArrayList<Long> selectLeafGroupIds(long groupId) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public ArrayList<MyGroup> selectAncestorGroups(long groupId) {
		return convertEasy(selectAncestorGroupIds(groupId));
	}

	@Override
	public ArrayList<MyGroup> selectDescendantGroups(long groupId) {
		return convertEasy(selectDescendantGroupIds(groupId));
	}

	@Override
	public ArrayList<MyGroup> selectLeafGroups(long groupId) {
		// TODO Auto-generated method stub
		return null;
	}
	
	//helper
		private ArrayList<MyGroup> convertEasy(ArrayList<Long> myGroupIds){
			ArrayList<MyGroup> myGroups = new ArrayList<MyGroup>();
			for(Long currentLong:myGroupIds){
				myGroups.add(myGroupDAOImpl.selectMyGroupById(currentLong));
			}
			return myGroups;
		}

}
